from moviepy.editor import *
import os
import re
import argparse

input_path = r'./input'
output_path = r'./output'


# 这个函数主要判断视频的音频是什么类型
def get_audio_format(audio: AudioFileClip) -> str:
    audio_code = audio.reader.acodec
    if audio_code in ['mp3','m4a']:
        return audio_code
    # (⊙﹏⊙) 貌似很多都是写无损，转出来的音频太大了还是直接写mp3吧，别用wav了
    elif audio_code in ['pcm_s16le']: # 这是一种无损格式，但问题是直接按照写入的wav文件太大了
        return 'mp3'
    else: # 兜底用mp3
        return 'mp3'


# 这个是自动获取input和output文件夹中，未有对应音频的视频
def get_target_vedio_name()->list: # 返回的是视频名
    # 方法
    get_files_func: function = lambda path: next(os.walk(path))[2]
    def clear_name_func():
        pattern = re.compile(r'^[\s\S]*(?=\.(?:mp4|mp3|wav|m4a)$)')
        def run(name: str) -> str:
            return pattern.search(name).group(0)
        return run
    clear_name_instance = clear_name_func()
    clear_files_func: function = lambda file_list: tuple(clear_name_instance(i) for i in file_list)
    # 变量
    input_dir = input_path
    output_dir = output_path
    input_file_list = get_files_func(input_dir)
    output_file_list = get_files_func(output_dir)
    output_file_clear_tuple = clear_files_func(output_file_list)
    # 操作
    result = list(filter(lambda name: clear_name_instance(name) not in output_file_clear_tuple, input_file_list))
    return result


    

# 传入input中的文件名
def file_convert_audio(files: list)->None:
    def to_audio(input_vedio: str):
        # 输入MP4文件路径
        if input_vedio[-4:] != r'.mp4':
            print(rf'This is not vedio: {input_vedio}')
            pass
        input_vedio_path = input_path +"/"+ input_vedio
        # 加载视频文件
        video = VideoFileClip(input_vedio_path)
        # 提取音频
        audio: AudioFileClip = video.audio
        audio_format:str = get_audio_format(audio)
        output_audio = input_vedio_path.replace(input_path, output_path)
        output_audio = re.sub(r'\.mp4$', f'.{audio_format}', output_audio)

        print(f'《{input_vedio}》 start')
        print(f"format: {audio_format}")# 音频格式
        print(f"fps：{audio.fps}")#采样频率
        print(fr"path: {output_audio}")# 写入路径
        # 输出MP3文件
        audio.write_audiofile(output_audio ,audio.fps)
        print(fr"《{input_vedio}》 done")# 
        print('================================')
    if len(files) == 0: 
        print("No vedio needs to be convert to audio")
        return
    for i in files:
        to_audio(i)



if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="一个简单的视频提取音频的脚本")
    option_arg_sign = 'op'
    file_arg_sign = 'f'
    parser.add_argument(f"--{option_arg_sign}", help="option: default or single",type=str, required=False , default='default')
    parser.add_argument(f"--{file_arg_sign}", help='视频名称：视频记得放input文件夹', type=str, required=False)

    args = parser.parse_args()
    
    option: str = getattr(args, option_arg_sign)
    if option == 'default':
        target_vedio_name: list = get_target_vedio_name()
        file_convert_audio(target_vedio_name)
    elif option == 'single':
        filename: str = getattr(args, file_arg_sign)
        file_convert_audio([filename])

    